package com.sxj.springsourcecode.springframework.io.support;

import com.sxj.springsourcecode.springframework.factory.config.BeanDefinition;
import com.sxj.springsourcecode.springframework.factory.config.BeanDefinitionRegistry;
import com.sxj.springsourcecode.springframework.factory.config.BeanRefrence;
import com.sxj.springsourcecode.springframework.io.config.Resource;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;

import static com.sxj.springsourcecode.springframework.constants.Constant.*;

/**
 * @ProjectName: spring-source-code
 * @Package: com.sxj.springsourcecode.springframework.io.support
 * @ClassName: XmlBeanDefinitionReader
 * @Author: sxj
 * @Description:
 * @Date: 2024/2/21 22:49
 * @Version: 1.0.0
 */
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader{
    public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
        super(registry);
    }

    @Override
    public void loadBeanDefinitions(Resource resource) {
        InputStream inputStream = resource.getInputStream();
        try {
            doLoadBeanDefinitions(inputStream);
        } catch (ParserConfigurationException | IOException | SAXException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 加载bean定义
     * @param inputStream
     */
    private void doLoadBeanDefinitions(InputStream inputStream) throws ParserConfigurationException, IOException, SAXException, ClassNotFoundException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = factory.newDocumentBuilder();
        Document doc = documentBuilder.parse(inputStream);
        Element root = doc.getDocumentElement();
        NodeList childNodes = root.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node node = childNodes.item(i);
            if (node instanceof Element){
                Element ele = (Element) node;
                String beanName = ele.getAttribute(BEAN_NAME);
                String beanClass = ele.getAttribute(BEAN_CLASS);
                Class<?> aClass = Class.forName(beanClass);
                //创建bean定义
                BeanDefinition beanDefinition = new BeanDefinition(aClass);
                //设置初始化和销毁方法
                String initMethodName = ele.getAttribute(INIT_METHOD);
                if (StringUtils.hasText(initMethodName)){
                    beanDefinition.setInitMethodName(initMethodName);
                }
                String destoryMethodName = ele.getAttribute(DESTROY_METHOD);
                if (StringUtils.hasText(destoryMethodName)){
                    beanDefinition.setDestroyMethodName(destoryMethodName);
                }
                //设置bean属性
                NodeList eleChildNodes = ele.getChildNodes();
                for (int j = 0; j < eleChildNodes.getLength(); j++) {
                    Node node1 = eleChildNodes.item(j);
                    if (node1 instanceof Element){
                        Element cEle = (Element) node1;
                        String pName = cEle.getAttribute(PROPERTY_NAME);
                        Object pVal = cEle.getAttribute(PROPERTY_VALUE);
                        String pRef = cEle.getAttribute(PROPERTY_REF);
                        if (StringUtils.hasText(pRef)){
                            pVal = new BeanRefrence(pRef);
                        }
                        beanDefinition.setPropertyValue(pName,pVal);
                    }
                }

                //注册
                getRegistry().registerBeanDefiniton(beanName,beanDefinition);

            }
        }
    }
}
